﻿using db_manage.dll.db;
using db_manage.model;
using db_manage.model.db;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace db_manage.dll.manage
{
    /// <summary>
    /// 备份业务
    /// </summary>
    public partial class manage
    {
        public static string db_bak(Action exec_after_each)
        {
            //获取数据库
            switch (db_manage_config.db_config_bak.content)
            {
                case db_config_bak_content.备份勾选服务器的所有数据库:
                    db_info_list_get(true, true);
                    break;
                case db_config_bak_content.仅备份当前勾选数据库:
                    break;
            }

            manage.db_task(
                new req_db_task()
                {
                    exec_action = (db_info) =>
                     {
                         var infosql = $" insert into db_manage_record(vernum, updatetime,updatestatus, remark,taketime,sqlstr)  values(@vernum, @updatetime,@updatestatus,@remark,@taketime,@sqlstr) ";
                         try
                         {
                             //查询旧记录
                             //-上次完整备份
                             var last_sql = "select updatetime updatetime,sqlstr str from db_manage_record where updatestatus=1 and vernum =@vernum order by updatetime desc";
                             var last_dbinfo_full = db_factory.Instance.sql_queryfirstordefault<db_manage_record>(db_info, last_sql, new { vernum = (int)vernum.完整备份 });
                             var interval_full = db_info.db_link_info.db_config_bak_sub.interval_full;
                             if (interval_full > 0
                              && (last_dbinfo_full == null || last_dbinfo_full.updatetime.Value.AddMinutes(interval_full) <= DateTime.Now))
                             {
                                 //已达到完整备份间隔时间，进行完整备份
                                 db_info.vernum = (int)vernum.完整备份;
                             }
                             else
                             {
                                 var interval_diff = db_info.db_link_info.db_config_bak_sub.interval_diff;
                                 //完整备份不满足则查看差异备份
                                 var last_dbinfo_diff = db_factory.Instance.sql_queryfirstordefault<db_manage_record>(db_info, last_sql, new { vernum = (int)vernum.差异备份 });
                                 if (last_dbinfo_full.updatetime.Value.AddMinutes(interval_diff) <= DateTime.Now
                                 && (interval_diff > 0
                                 && (last_dbinfo_diff == null || last_dbinfo_diff.updatetime.Value.AddMinutes(interval_diff) <= DateTime.Now)))
                                 {
                                     //离上次完整备份已达时间间隔，且未有差异备份或差异备份也达到时间间隔，则进行差异备份
                                     db_info.vernum = (int)vernum.差异备份;
                                 }
                             }

                             if (db_info.vernum == null)
                             {
                                 //未满足备份要求
                                 db_record_set(db_info, true, "无需操作");
                                 return;
                             }

                             //备份数据库
                             var bak_name = db_factory.Instance.bak(db_info, new db_bak_param()
                             {
                                 bak_diff = db_info.vernum == (int)vernum.差异备份,
                                 dir_bak = db_info.db_link_info.db_config_bak_sub.dir_bak,
                                 dir_username = db_info.db_link_info.db_config_bak_sub.dir_username,
                                 dir_pwd = db_info.db_link_info.db_config_bak_sub.dir_pwd,
                             });

                             //备份完成后删除历史备份（需要可以访问远程）
                             var del_filename_pre = string.Empty;
                             if (db_info.vernum == (int)vernum.完整备份 && db_info.db_link_info.db_config_bak_sub.bak_full_del)
                             {
                                 del_filename_pre = $"{db_info.name}_";
                             }
                             else if (db_info.vernum == (int)vernum.差异备份 && db_info.db_link_info.db_config_bak_sub.bak_diff_del)
                             {
                                 del_filename_pre = $"{db_info.name}_diff_";
                             }
                             if (!string.IsNullOrEmpty(del_filename_pre))
                             {
                                 if (Directory.Exists(db_info.db_link_info.db_config_bak_sub.dir_bak))
                                 {
                                     foreach (string filename in Directory.GetFiles(db_info.db_link_info.db_config_bak_sub.dir_bak, $"{del_filename_pre}*"))
                                     {
                                         if (File.Exists(filename) && !filename.Contains(bak_name))
                                         {
                                             File.Delete(filename);
                                         }
                                     }
                                 }
                             }

                             //执行完成记录
                             db_record_set(db_info, true);
                             db_factory.Instance.sql_exec(db_info, infosql, db_info);
                         }
                         catch (Exception ex)
                         {
                             db_record_set(db_info, false, null, ex);
                             //添加记录
                             db_factory.Instance.sql_exec(db_info, infosql, db_info);
                             if (!(manage.db_manage_config.db_config_exec.ingore_fail ?? false))//不忽略错误则停止，否则继续执行
                             {
                                 return;
                             }
                         }
                     },
                    finished_action = () =>
                    {
                        //完成后重新启动任务
                        if (manage.db_manage_config.db_config_bak.enable)
                        {
                            db_bak(exec_after_each);
                        }
                    }
                });

            return "已启动备份";
        }

        /// <summary>
        /// 检查服务器的时间，不满足的暂停，满足的继续执行
        /// </summary>
        public static void bak_time_check()
        {
            if (_db_link_info == null)
            {
                return;
            }

            _db_link_info.ForEach(db_link_info =>
            {
                var now_db_config_bak_sub = db_link_info?.db_config_bak_sub;
                if (now_db_config_bak_sub == null)
                {
                    //未配置的服务器不启用
                    return;
                }

                if ((now_db_config_bak_sub.time_start.TimeOfDay <= DateTime.Now.TimeOfDay || now_db_config_bak_sub.time_start.TimeOfDay == new TimeSpan(0, 0, 0))
                && (now_db_config_bak_sub.time_end.TimeOfDay >= DateTime.Now.TimeOfDay || now_db_config_bak_sub.time_end.TimeOfDay == new TimeSpan(0, 0, 0)))
                {
                    //在范围内启用
                    manage.bak_start_end(db_link_info, true);
                }
                else
                {
                    //不在范围内则禁用
                    manage.bak_start_end(db_link_info, false);
                }
            });
        }

    }
}
